---
title: User Interface
status: published
author: steveruizok
date: 3/22/2023
order: 7
keywords:
  - ui
  - interface
  - tools
  - shapes
  - custom
  - button
  - toolbar
  - styles
---

The user interface in tldraw includes the menus, toolbars, keyboard shortcuts, and analytics events in the editor.

## Hiding the UI

You can hide the default tldraw user interface entirely using the `hideUi` prop. This turns off both the visuals as well as the keyboard shortcuts.

```tsx
function Example() {
	return <Tldraw hideUi />
}
```

Here's [an example](https://examples.tldraw.com/hide-ui) of what that looks like. Note that while you can't select any other tools using the keyboard shortcuts, you can still use the `setCurrentTool` method to change the tool. If you open the console and enter:

```ts
editor.setCurrentTool('draw')
```

...then you can start drawing.

All of our user interface works by controlling the editor via its `Editor` methods. If you hide the user interface, you can still use these same editor's methods to control the editor. Our [custom user interface example](https://examples.tldraw.com/custom-ui) shows this in action.

The source for these examples are available in the [tldraw repository](https://github.com/tldraw/tldraw/blob/main/apps/examples/src) or in a [sandbox here](https://stackblitz.com/github/tldraw/tldraw/tree/examples?file=src%2Findex.tsx).

## Overrides

The content of tldraw's menus can be controlled via the `overrides` prop. This prop accepts a [TLUiOverrides](/gen/tldraw/TLUiOverrides) object, which has methods for each part of the user interface, such as the `toolbar` or `keyboardShortcutsMenu`.

### Actions

The user interface has a set of shared `actions` that are used in the menus and keyboard shortcuts. These actions can be overridden by passing a new set of actions to the `overrides.actions` method.

To create, update, or delete actions, provide an `actions` method that receives both the editor and the [default actions](https://github.com/tldraw/tldraw/blob/main/packages/tldraw/src/lib/ui/hooks/useActions.tsx) and returns a mutated actions object.

```ts
const myOverrides: TLUiOverrides = {
	actions(editor, actions) {
		// You can delete actions, but remember to
		// also delete the menu items that reference them!
		delete actions['insert-embed']

		// Create a new action or replace an existing one
		actions['my-new-action'] = {
			id: 'my-new-action',
			label: 'My new action',
			readonlyOk: true,
			kbd: '$u',
			onSelect(source: any) {
				// Whatever you want to happen when the action is run
				window.alert('My new action just happened!')
			},
		}
		return actions
	},
}
```

The `actions` object is a map of [TLUiActionItem](/gen/tldraw/TLUiActionItem)s, with each item keyed under its `id`.

### Tools

Tools work in the same manner as actions. You can override the default tools by passing a `tools` method that accepts the [default tools object](https://github.com/tldraw/tldraw/blob/main/packages/tldraw/src/lib/ui/hooks/useTools.tsx) and returns a mutated version of that object.

```ts
const myOverrides: TLUiOverrides = {
	tools(editor, tools) {
		// Create a tool item in the ui's context.
		tools.card = {
			id: 'card',
			icon: 'color',
			label: 'tools.card',
			kbd: 'c',
			readonlyOk: false,
			onSelect: () => {
				// Whatever you want to happen when the tool is selected
				editor.setCurrentTool('card')
			},
		}
		return tools
	},
}
```

The `tools` object is a map of [TLUiToolItem](/gen/tldraw/TLUiToolItem)s, with each item keyed under its `id`.

### Toolbar and Menus

The remaining overrides are for toolbar and the various menus: the main menu, actions menu, context menu, help menu, and the keyboard shortcuts menu.

Each of these overrides accepts a method that receives the default menu schema and returns a mutated version of that schema.

```ts
const myOverrides: TLUiOverrides = {
	actions(editor, actions) {
		// Create a new action or replace an existing one
		actions['my-new-action'] = {
			id: 'my-new-action',
			label: 'My new action',
			readonlyOk: true,
			kbd: '$u',
			onSelect(source: any) {
				window.alert('My new action just happened!')
			},
		}
		return actions
	},
	contextMenu(editor, contextMenu, { actions }) {
		const newMenuGroup = menuGroup('my-items', newMenuItem)
		contextMenu.unshift(newMenuItem)
		return contextMenu
	},
	menu(editor, menu, { actions }) {
		// using the findMenuItem helper
		const fileMenu = findMenuItem(menu, ['menu', 'file'])
		if (fileMenu.type === 'submenu') {
			// add the new item to the file menu's children
			const newMenuItem = menuItem(actions['my-new-action'])
			fileMenu.children.unshift(newMenuItem)
		}
		return menu
	},
}
```

A menu schema is an array of either [submenus](/gen/tldraw/TLUiSubMenu), [groups](/gen/tldraw/TLUiMenuGroup), [items](/gen/tldraw/TLUiMenuItem), or [custom items](/gen/tldraw/TLUiCustomMenuItem). Each group or submenu may include any of the other types as its children.

The menu schema is stateful. Referencing atomic properties (such as computed values in the editor) will cause the menu to update when those values change. If you wish for a menu item to disappear from the menu, you can return `null` from the menu method. You can also provide additional options for each item, `disabled` or `checked`.

```ts
const myOverrides: TLUiOverrides = {
	menu(editor, menu, { actions }) {
		const selectedShapes = editor.getSelectedShapeIds().length

		const newMenuGroup = menuGroup(
			'my-actions',
			selectedShapes > 0 ? menuItem(actions['action-a']) : null,
			menuItem(actions['action-b'], { disabled: selectedShapes < 3 })
		)

		menu.unshift(newMenuGroup)

		return menu
	},
}
```

It's recommmended to explore the [default menu schema](https://github.com/tldraw/tldraw/blob/main/packages/tldraw/src/lib/ui/hooks/useMenuSchema.tsx) in order to understand how menu items work.

### Translations

The `translations` method accepts a table of new translations. For example, if you wanted a tool to reference a key `"tools.card"`, then you should at minimum provide an english translation for this key.

```ts
const myOverrides: TLUiOverrides = {
	translations: {
		en: {
			'tools.card': 'Card',
		},
	},
}
```

## Events

The [Tldraw](?) component has a prop, `onUiEvent`, that the user interface will call when certain events occur.

```tsx
function Example() {
	function handleEvent(name, data) {
		// do something with the event
	}

	return <Tldraw onUiEvent={handleEvent} />
}
```

The `onUiEvent` callback is called with the name of the event as a string and an object with information about the event's source (e.g. `menu` or `context-menu`) and possibly other data specific to each event, such as the direction in an `align-shapes` event.

Note that `onUiEvent` is only called when interacting with the user interface. It is not called when running commands manually against the app, e.g. calling [Editor#alignShapes](?) will not call `onUiEvent`.

See the [tldraw repository](https://github.com/tldraw/tldraw/tree/main/apps/examples) for an example of how to customize tldraw's user interface.
